<template>
  <div class="cesium-performance-monitor" :style="monitorStyle" @click="toggleExpanded">
    <!-- 基础信息始终显示 -->
    <div class="monitor-header">
      <span>性能监控</span>
      <span class="toggle-button">{{ expanded ? '▼' : '▶' }}</span>
    </div>
    <div class="performance-item" :class="{ warning: fps < 20 }">
      FPS: {{ fps }} <span class="status-indicator" :class="getPerformanceClass(fps, 30, 20)"></span>
    </div>

    <!-- 展开后显示详细信息 -->
    <div v-if="expanded" class="expanded-content">
      <div class="performance-group">
        <div class="group-title">内存使用</div>
        <div class="performance-item" :class="{ warning: memoryLeakProbability > 70 }">
          当前: {{ memory }} MB <span class="status-indicator" :class="getMemoryStatusClass()"></span>
        </div>
        <div class="performance-item">
          峰值: {{ peakMemory }} MB
        </div>
        <div class="performance-item">
          趋势: {{ memoryTrend }}
          <span class="trend-indicator" :class="getMemoryTrendClass()"></span>
        </div>
        <div v-if="memoryLeakProbability > 0" class="performance-item" :class="{ warning: memoryLeakProbability > 70 }">
          内存泄漏概率: {{ memoryLeakProbability }}%
        </div>
      </div>

      <div class="performance-group">
        <div class="group-title">场景对象</div>
        <div class="performance-item" :class="{ warning: primitiveCount > 5000 }">
          Primitives: {{ primitiveCount }}
        </div>
        <div class="performance-item" :class="{ warning: entityCount > 1000 }">
          Entities: {{ entityCount }}
        </div>
        <div class="performance-item">
          纹理内存: {{ textureMemory }} MB
        </div>
      </div>

      <div class="performance-group">
        <div class="group-title">渲染性能</div>
        <div class="performance-item" :class="{ warning: frameTime > 50 }">
          帧时间: {{ frameTime.toFixed(2) }}ms
          <span class="status-indicator" :class="getPerformanceClass(16.67 / frameTime * 100, 0.8, 0.5)"></span>
        </div>
        <div class="performance-item" :class="{ warning: gpuMemoryUsage > gpuMemoryLimit * 0.8 && gpuMemoryLimit > 0 }">
          GPU内存: {{ gpuMemoryUsage }}MB / {{ gpuMemoryLimit > 0 ? gpuMemoryLimit + 'MB' : '未知' }}
        </div>
        <div class="performance-item">
          渲染调用: {{ drawCallsPerFrame }}
        </div>
      </div>

      <div class="performance-group">
        <div class="group-title">场景状态</div>
        <div class="performance-item">
          相机高度: {{ cameraHeight }}米
        </div>
        <div class="performance-item">
          视锥体三角形: {{ trianglesInFrustum }}
        </div>
        <div class="performance-item">
          流畅度评级:
          <span :class="getFluidityClass()">{{ fluidityRating }}</span>
        </div>
      </div>

      <div v-if="warnings.length > 0" class="performance-group warnings-group">
        <div class="group-title">警告</div>
        <div v-for="(warning, index) in warnings" :key="index" class="warning-item">
          {{ warning }}
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import * as Cesium from 'cesium';
import { ref, onMounted, onBeforeUnmount, defineProps, computed, watch } from 'vue';

const props = defineProps({
  viewer: {
    type: Object,
    required: true
  },
  position: {
    type: String,
    default: 'top-right'
  },
  backgroundColor: {
    type: String,
    default: 'rgba(0, 0, 0, 0.7)'
  }
});

// UI状态
const expanded = ref(false);
function toggleExpanded () {
  expanded.value = !expanded.value;
}

// 基本性能数据
const fps = ref(0);
const memory = ref(0);
const primitiveCount = ref(0);
const entityCount = ref(0);
const cameraHeight = ref(0);

// 扩展性能数据
const peakMemory = ref(0);
const memoryHistory = ref([]);
const memoryTrend = ref('稳定');
const memoryLeakProbability = ref(0);
const frameTime = ref(0);
const gpuMemoryUsage = ref(0);
const gpuMemoryLimit = ref(0);
const drawCallsPerFrame = ref(0);
const trianglesInFrustum = ref(0);
const textureMemory = ref(0);
const fluidityRating = ref('良好');
const warnings = ref([]);

// 追踪变量
let lastFrameTime = performance.now();
let frameCount = 0;
let updateInterval = null;
let memoryCheckInterval = null;
let frameTimeHistory = [];
let frameTimeSum = 0;
let frameTimeSamples = 0;
const maxMemorySamples = 60; // 1分钟(假设采样间隔为1秒)
const maxFrameSamples = 60;

// 定位样式
const monitorStyle = computed(() => {
  const styles = {
    backgroundColor: props.backgroundColor,
    color: 'white',
    padding: '10px',
    borderRadius: '5px',
    fontFamily: 'Arial, sans-serif',
    fontSize: '14px',
    zIndex: '1000',
    position: 'absolute',
    cursor: 'pointer',
    boxShadow: '0 0 10px rgba(0,0,0,0.5)',
    minWidth: '200px',
    transition: 'all 0.3s ease',
  };

  // 根据position属性设置位置
  switch (props.position) {
    case 'top-left':
      styles.top = '10px';
      styles.left = '10px';
      break;
    case 'top-right':
      styles.top = '10px';
      styles.right = '10px';
      break;
    case 'bottom-left':
      styles.bottom = '10px';
      styles.left = '10px';
      break;
    case 'bottom-right':
      styles.bottom = '10px';
      styles.right = '10px';
      break;
    default:
      styles.top = '10px';
      styles.left = '10px';
      break;
  }

  return styles;
});

// 计算性能状态类
function getPerformanceClass (value, good, medium) {
  if (value >= good) return 'good';
  if (value >= medium) return 'medium';
  return 'bad';
}

// 计算内存状态类
function getMemoryStatusClass () {
  const memoryPercent = window.performance && window.performance.memory ?
    (window.performance.memory.usedJSHeapSize / window.performance.memory.jsHeapSizeLimit) * 100 : 0;

  if (memoryPercent > 90) return 'bad';
  if (memoryPercent > 70) return 'medium';
  return 'good';
}

// 计算内存趋势类
function getMemoryTrendClass () {
  if (memoryTrend.value === '上升') return 'trend-up';
  if (memoryTrend.value === '下降') return 'trend-down';
  return '';
}

// 计算流畅度类
function getFluidityClass () {
  switch (fluidityRating.value) {
    case '极佳': return 'fluidity-excellent';
    case '良好': return 'fluidity-good';
    case '一般': return 'fluidity-fair';
    case '较差': return 'fluidity-poor';
    default: return '';
  }
}

// 计算FPS
function calculateFps () {
  const now = performance.now();
  const elapsed = now - lastFrameTime;

  // 计算帧间时间
  if (frameCount > 0) {
    const currentFrameTime = elapsed / frameCount;
    frameTimeSum += currentFrameTime;
    frameTimeHistory.push(currentFrameTime);
    frameTimeSamples++;

    // 保持历史记录在限定范围内
    if (frameTimeHistory.length > maxFrameSamples) {
      const oldFrameTime = frameTimeHistory.shift();
      frameTimeSum -= oldFrameTime;
      frameTimeSamples--;
    }

    frameTime.value = frameTimeSum / frameTimeSamples;
  }

  if (elapsed >= 1000) { // 每秒更新一次
    fps.value = Math.round(frameCount * 1000 / elapsed);
    frameCount = 0;
    lastFrameTime = now;

    // 更新其他性能指标
    updatePerformanceMetrics();

    // 分析流畅度
    analyzePerformance();
  }
  frameCount++;

  // 请求下一帧
  requestAnimationFrame(calculateFps);
}

// 更新性能指标
function updatePerformanceMetrics () {
  if (!props.viewer) return;

  // 计算primitives数量
  primitiveCount.value = props.viewer.scene.primitives.length;

  // 计算entities数量
  entityCount.value = props.viewer.entities.values.length;

  // 更新相机高度
  const cameraPosition = props.viewer.camera.positionCartographic;
  cameraHeight.value = Math.round(cameraPosition.height);

  // 获取内存使用情况(如果浏览器支持)
  if (window.performance && window.performance.memory) {
    const currentMemory = Math.round(window.performance.memory.usedJSHeapSize / (1024 * 1024));
    memory.value = currentMemory;

    // 更新峰值内存
    if (currentMemory > peakMemory.value) {
      peakMemory.value = currentMemory;
    }

    // 记录内存历史用于检测泄漏
    memoryHistory.value.push(currentMemory);
    if (memoryHistory.value.length > maxMemorySamples) {
      memoryHistory.value.shift();
    }
  } else {
    memory.value = "N/A";
  }

  // 估计GPU占用
  try {
    // 尝试从WebGL上下文获取信息
    const gl = props.viewer.scene.context._gl;
    const ext = gl.getExtension('WEBGL_debug_renderer_info');
    if (ext) {
      const vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);
      const renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);

      // 尝试估算GPU内存
      if (window.chrome && window.chrome.gpuInfo) {
        const gpuInfo = window.chrome.gpuInfo.getInfo();
        if (gpuInfo && gpuInfo.auxAttributes && gpuInfo.auxAttributes.videoMemory) {
          gpuMemoryLimit.value = gpuInfo.auxAttributes.videoMemory;
        }
      }
    }

    // 估算纹理内存占用
    let textureMem = 0;
    if (props.viewer.scene.context.textures) {
      Object.values(props.viewer.scene.context.textures).forEach(texture => {
        if (texture && texture.pixelFormat && texture.width && texture.height) {
          // 简化的估算方式，实际计算需要考虑像素格式等
          textureMem += (texture.width * texture.height * 4) / (1024 * 1024);
        }
      });
      textureMemory.value = Math.round(textureMem);
    }

    // 估算渲染调用次数
    drawCallsPerFrame.value = props.viewer.scene.debugShowDrawCountsObservable ?
      props.viewer.scene.debugShowDrawCountsObservable._value : 'N/A';

    // 估算视锥体中的三角形数
    const primitive = props.viewer.scene.primitives;
    let totalTriangles = 0;
    for (let i = 0; i < primitive.length; i++) {
      if (primitive.get(i) && primitive.get(i).geometryInstances) {
        const geometry = primitive.get(i).geometryInstances;
        if (Array.isArray(geometry)) {
          geometry.forEach(geo => {
            if (geo && geo.geometry && geo.geometry.indices) {
              totalTriangles += geo.geometry.indices.length / 3;
            }
          });
        } else if (geometry && geometry.geometry && geometry.geometry.indices) {
          totalTriangles += geometry.geometry.indices.length / 3;
        }
      }
    }
    trianglesInFrustum.value = Math.round(totalTriangles);

    // 估算GPU内存使用
    gpuMemoryUsage.value = Math.round((textureMemory.value + (trianglesInFrustum.value * 0.0001)));
  } catch (e) {
    console.log('无法获取GPU信息', e);
  }
}

// 分析内存泄漏趋势
function analyzeMemoryLeak () {
  if (memoryHistory.value.length < 10) return; // 需要足够的数据点

  // 简单线性回归分析内存趋势
  let sumX = 0;
  let sumY = 0;
  let sumXY = 0;
  let sumX2 = 0;
  const n = memoryHistory.value.length;

  for (let i = 0; i < n; i++) {
    sumX += i;
    sumY += memoryHistory.value[i];
    sumXY += i * memoryHistory.value[i];
    sumX2 += i * i;
  }

  const slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);

  // 设置内存趋势
  if (slope > 0.5) {
    memoryTrend.value = '上升';

    // 根据趋势斜率和持续时间估计内存泄漏概率
    const minutes = Math.floor(memoryHistory.value.length / 60);
    if (minutes >= 1) {
      // 如果内存持续上升超过1分钟，可能存在内存泄漏
      memoryLeakProbability.value = Math.min(100, Math.round(slope * 20 * minutes));

      // 如果概率超过阈值，添加警告
      if (memoryLeakProbability.value > 70 && !warnings.value.some(w => w.includes('内存泄漏'))) {
        warnings.value.push(`警告：可能存在内存泄漏，内存持续上升${minutes}分钟`);
      }
    }
  } else if (slope < -0.5) {
    memoryTrend.value = '下降';
    memoryLeakProbability.value = 0;
  } else {
    memoryTrend.value = '稳定';
    memoryLeakProbability.value = 0;
  }
}

// 分析性能
function analyzePerformance () {
  const warnings = [];

  // FPS检查
  if (fps.value < 20) {
    warnings.push(`低帧率警告: ${fps.value} FPS`);
  }

  // 内存使用检查
  if (memory.value !== 'N/A' && memory.value > 500) {
    warnings.push(`高内存使用: ${memory.value}MB`);
  }

  // primitives数量检查
  if (primitiveCount.value > 5000) {
    warnings.push(`Primitives数量过多: ${primitiveCount.value}`);
  }

  // 实体数量检查
  if (entityCount.value > 1000) {
    warnings.push(`实体数量过多: ${entityCount.value}`);
  }

  // 更新警告列表
  warnings.value = warnings;

  // 计算流畅度评级
  if (fps.value >= 50 && frameTime.value < 16) {
    fluidityRating.value = '极佳';
  } else if (fps.value >= 30 && frameTime.value < 33) {
    fluidityRating.value = '良好';
  } else if (fps.value >= 20 && frameTime.value < 50) {
    fluidityRating.value = '一般';
  } else {
    fluidityRating.value = '较差';
  }
}

// 组件加载后启动性能监控
onMounted(() => {
  if (props.viewer) {
    // 开始计算FPS和监控性能
    calculateFps();

    // 每秒更新一次性能指标
    updateInterval = setInterval(() => {
      updatePerformanceMetrics();
    }, 1000);

    // 每分钟分析一次内存泄漏
    memoryCheckInterval = setInterval(() => {
      analyzeMemoryLeak();
    }, 60000); // 60秒一次

    // 首次分析
    setTimeout(() => {
      analyzePerformance();
    }, 5000); // 给应用一些时间加载资源
  }
});

// 组件卸载前停止性能监控
onBeforeUnmount(() => {
  if (updateInterval) {
    clearInterval(updateInterval);
  }
  if (memoryCheckInterval) {
    clearInterval(memoryCheckInterval);
  }
});

// 监视viewer属性变化
watch(() => props.viewer, (newVal) => {
  if (newVal) {
    // 如果viewer更新，重新启动监控
    calculateFps();
    updatePerformanceMetrics();
  }
});
</script>

<style scoped>
.cesium-performance-monitor {
  user-select: none;
  min-width: 200px;
  max-width: 300px;
  pointer-events: auto;
}

.monitor-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  font-weight: bold;
  border-bottom: 1px solid rgba(255, 255, 255, 0.3);
  padding-bottom: 5px;
}

.toggle-button {
  font-size: 12px;
  opacity: 0.7;
}

.performance-item {
  line-height: 1.5;
  font-size: 13px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 2px 0;
}

.expanded-content {
  margin-top: 10px;
  font-size: 12px;
}

.performance-group {
  margin-bottom: 12px;
  padding: 5px;
  background-color: rgba(255, 255, 255, 0.05);
  border-radius: 3px;
}

.group-title {
  font-weight: bold;
  margin-bottom: 5px;
  opacity: 0.8;
  font-size: 12px;
}

.status-indicator {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-left: 8px;
}

.good {
  background-color: #4caf50;
}

.medium {
  background-color: #ff9800;
}

.bad {
  background-color: #f44336;
}

.warning {
  color: #ff9800;
}

.warnings-group {
  background-color: rgba(244, 67, 54, 0.1);
  border-left: 3px solid #f44336;
}

.warning-item {
  padding: 3px 0;
  font-size: 12px;
}

.trend-indicator {
  margin-left: 5px;
  width: 0;
  height: 0;
  display: inline-block;
}

.trend-up {
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 8px solid #f44336;
}

.trend-down {
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 8px solid #4caf50;
}

.fluidity-excellent {
  color: #4caf50;
  font-weight: bold;
}

.fluidity-good {
  color: #8bc34a;
}

.fluidity-fair {
  color: #ff9800;
}

.fluidity-poor {
  color: #f44336;
}
</style>